package Soul

import (
	codecs "sanguo/codec/cs"
	"sanguo/node/common/GlobalConstData"
	"sanguo/node/common/com_type"
	"sanguo/node/common/transaction"
	"sanguo/node/node_game"
	"sanguo/node/node_game/module/role"
	"sanguo/node/node_game/user"
	table_GamePlay "sanguo/node/table/excel/table/GamePlay"
	table_Soul "sanguo/node/table/excel/table/Soul"
	cs_message "sanguo/protocol/cs/message"
	"time"

	"github.com/golang/protobuf/proto"
)

type transactionSoulUpStar struct {
	transaction.TransactionBase
	user    *user.User
	req     *codecs.Message
	resp    *cs_message.SoulUpStarToC
	errcode cs_message.EnumType
}

func (this *transactionSoulUpStar) GetModuleName() string {
	return "Soul"
}

func (this *transactionSoulUpStar) GetReplyMsg() proto.Message {
	return &cs_message.SoulUpStarToC{}
}

func (this *transactionSoulUpStar) SetExpiredTime(expired time.Time) {
	this.Expired = expired
}

func (this *transactionSoulUpStar) GetExpiredTime() time.Time {
	return this.Expired
}

func (this *transactionSoulUpStar) Begin() {

	this.resp = &cs_message.SoulUpStarToC{}
	msg := this.req.GetData().(*cs_message.SoulUpStarToS)

	roleModule := this.user.GetModuleByName("role").(*role.RoleModule)
	role := roleModule.CurrentRole()
	if role == nil || !role.IsRoleModleData() {
		node_game.Infoln(role.GetUserID(), "SoulUpStar fail : role is nil")
		this.errcode = cs_message.EnumType_ERROR
		this.user.EndTrans(this)
		return
	}
	node_game.Infof("%s %d Call SoulUpStar id:%d ", role.GetUserID(), role.GetID(), msg.GetToSoulId())

	//验证功能开启
	if role.GetLev() < table_GamePlay.Table_.IDMap[com_type.GamePaly_Soul].UnlockLevel {
		node_game.Infoln(role.GetUserID(), role.GetID(), "Soul System is not Unlock")
		this.errcode = cs_message.EnumType_ERROR
		this.user.EndTrans(this)
		return
	}

	//武魂升星条件判断 三星以上才能升星
	boolSoul := func(toID uint64, fromID []uint64) bool {
		if len(fromID) == 0 {
			return false
		}

		toSoul := role.GetRoleSoul().GetSoul(toID)
		if toSoul == nil {
			return false
		} else {
			//星级已达上限
			if toSoul.StarLevel >= GlobalConstData.StarMaxLevel {
				return false
			}
			def := table_Soul.Table_.IDMap[toSoul.ConfigId]
			if def == nil || def.Rarity < com_type.Rarity_Epic { //三星以下
				return false
			}
		}

		for _, sID := range fromID {
			fromSoul := role.GetRoleSoul().GetSoul(sID)
			if fromSoul == nil {
				return false
			} else {
				def := table_Soul.Table_.IDMap[fromSoul.ConfigId]
				if def == nil || def.Rarity < com_type.Rarity_Epic {
					return false
				}
			}
		}
		return true
	}

	//升星条件判断
	if !boolSoul(msg.GetToSoulId(), msg.GetFromSoulId()) {
		node_game.Infoln(role.GetUserID(), role.GetID(), "SoulUpStar fail:Condition is fail")
		this.errcode = cs_message.EnumType_ERROR
		this.user.EndTrans(this)
		return
	}

	role.GetRoleSoul().SoulUpStar(msg.GetFromSoulId(), msg.GetToSoulId())

	//重新计算战斗属性
	role.TotalBattleAttr()

	//发送背包变化
	role.OnSoulDirty()

	node_game.Infoln(role.GetUserID(), role.GetID(), "SoulUpStar OK")
	this.errcode = cs_message.EnumType_OK
	this.user.EndTrans(this)
}

func (this *transactionSoulUpStar) End() {
	this.resp.Errcode = cs_message.EnumType(this.errcode).Enum()
	this.user.Reply(this.req.GetSeriNo(), this.resp)
}

func (this *transactionSoulUpStar) Timeout() {
	this.resp.Errcode = cs_message.EnumType(cs_message.EnumType_RETRY).Enum()
	this.user.EndTrans(this)
}

func init() {
	user.RegisterTransFunc(&cs_message.SoulUpStarToS{}, func(user *user.User, msg *codecs.Message) transaction.Transaction {
		return &transactionSoulUpStar{
			user: user,
			req:  msg,
		}
	})
}
